package office.stock.services;

import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.EnumSet;
import java.util.UUID;

import javax.ejb.Stateless;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@Stateless
public class FileSystemImageStorage implements ImageStorage {

    private final static Log log = LogFactory.getLog(FileSystemImageStorage.class);

    // TODO make this configurable
    private String imageFolder = "file:///d:/tmp/images/";

    @Override
    public String store(byte[] image) {
	String fileId = UUID.randomUUID().toString();
	log.debug("trying to store new image with id " + fileId);
	URI uri = URI.create(imageFolder + fileId);
	Path path = Paths.get(uri);
	try (FileChannel outChannel = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE))) {
	    ByteBuffer buffer = ByteBuffer.wrap(image);
	    outChannel.write(buffer);
	} catch (IOException e) {
	    log.error(e);
	}
	return fileId;
    }

    @Override
    public byte[] read(String id) {
	log.debug("looking for image with id " + id);
	byte[] image = new byte[0];

	if (id != null && !id.isEmpty()) {
	    image = readImage(id);
	}
	
	return image;
    }

    private byte[] readImage(String id) {
	byte[] image = new byte[0];
	URI uri = URI.create(imageFolder + id);
	Path path = Paths.get(uri);
	try (FileChannel channel = FileChannel.open(path, EnumSet.of(StandardOpenOption.READ))) {
	    long realSize = Files.size(path);
	    int size;
	    
	    if (realSize > Integer.MAX_VALUE) {
		log.error("Files greater than 2 GB are not supported");
		size = Integer.MAX_VALUE;
	    } else {
		size = (int) realSize;
	    }
	    
	    ByteBuffer buffer = ByteBuffer.allocate(size);
	    channel.read(buffer);
	    image = buffer.array();
	} catch (IOException e) {
	    log.error(e);
	}
//	if (Files.exists(path)) {
//	    try {
//		image = Files.readAllBytes(path);
//	    } catch (IOException e) {
//		log.error("can't read file " + path, e);
//	    }
//	}
	return image;
    }

    @Override
    public void remove(String id) {
	if (id != null && !id.isEmpty()) {
	    URI uri = URI.create(imageFolder + id);
	    Path path = Paths.get(uri);
	    try {
		Files.deleteIfExists(path);
	    } catch (IOException e) {
		log.error("can't delete the file " + path, e);
	    }
	}

    }

}
